/*////////////////////////////////////////////////////////////////////
//文档生成日期：2005.10.07
//
//(1)概述：
//类名称：GUIController
//类说明：
//       MVC中的控制器部分，负责界面事件的处理，以及决定该显示哪一个Form。
//
//所在子系统：RssOwlMIDlet
//
//系统总描述:
	    我们提供的RSS无线阅读器J2ME版本[开源]是一个可以下载到手机(例如Nokia7610)或者其他无线手持设备(例如PocketPC)的应用程序，用来阅读存在于Internet中广泛的RSS新闻源。

	 子系统描述：
		RSS无线阅读器的功能列表：
	RSS Feed列表
		添加Rss Feed
		编辑Rss Feed
		删除Rss Feed
	读取Rss Feed新闻
		查看新闻摘要
		重新读取Rss Feed新闻
	关于我


//(2)历史记录:
//创建人: 郑昀(2005.10.07)
//联系我: Google Talk >> zhengyun@gmail.com
//Blogs:    http://blog.csdn.net/zhengyun_ustc/以及http://www.cnblogs.com/zhengyun_ustc

//(3)版权声明:
//由于我这个版本的RSS J2ME阅读器也是基于Tommi和garrey源代码基础上改编而来的，
//所以决定遵照GPL协议的大意开放源代码，您可以自由传播和修改，在遵照GPL协议的约束条件的前提下。

//(4)相关资源:
1：《[J2ME]RSSOwlMidlet(RSS无线阅读器)开源说明》
2：《[J2ME]RSSOwlMidlet(RSS无线阅读器)设计说明》
3：下载源代码：

////////////////////////////////////////////////////////////////////*/
package com.zemo.control;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;

import com.zemo.midlet.RssReaderMIDlet;
import com.zemo.model.RssFeed;
import com.zemo.model.RssItem;
import com.zemo.tools.SResources;
import com.zemo.tools.Settings;
import com.zemo.view.About;
import com.zemo.view.RssFeedAdd;
import com.zemo.view.RssFeedEdit;
import com.zemo.view.RssFeedList;
import com.zemo.view.RssFeedOpen;
import com.zemo.view.RssItemView;

/**********************************************************
//	 GUIController
//
//	 Class Description:
//	 	MVC中的控制器部分，负责界面事件的处理，以及决定该显示哪一个Form。
//
//	 Author:
//	      zhengyun@zemo 2005.10.07
//
**********************************************************/
public class GUIController {
	public RssReaderMIDlet  rssMidlet;
	private Settings rssRecords;
	private RssFeedList list;
	private RssFeedAdd addForm;
	private RssItemView viewRssItemForm;
	private RssFeedEdit editForm;
	private RssFeedOpen openForm;
	private Alert alert;
	private About about;
	
	public GUIController(RssReaderMIDlet rssMain){
		rssMidlet = rssMain;
	}
	
	/**********************************************************
	//	 GUIController::init()
	//
	//	 Description:
	//	  初始化控制器：
	 * 		初始化各个Form界面
	 * 		设定先显示Rss Feed列表界面
	//
	//	 Parameters:
	//	 Return Values:
	//	 Author:
	//	      zhengyun@zemo 2005.10.07
	//
	**********************************************************/
	public void init(){
		try
		{
			rssRecords = Settings.getInstance(this, (MIDlet)rssMidlet);
		}
		catch(Exception exc)
		{
			System.out.println("!-- 构造Settings时发生异常! --!\n" + exc.getMessage());
		}
		// init ui
		list = new RssFeedList(SResources.FORM_TITLE_FEEDLIST, this, rssRecords.getRssFeeds());
		openForm = new RssFeedOpen(SResources.FORM_TITLE_READRSSFEED,this);
		addForm = new RssFeedAdd(SResources.FORM_TITLE_ADDRSSFEED,this);
		viewRssItemForm	= new RssItemView(SResources.FORM_TITLE_VIEWNEWS,this);
		editForm = new RssFeedEdit(SResources.FORM_TITLE_EDITRSSFEED,this);
		about =	new About(SResources.FORM_TITLE_ABOUTME);
		setCurrent(list);
	}


	/**********************************************************
	//	 GUIController::getRssFeedRecords()
	//
	//	 Description:
	//	  返回当前封装了RMS操作的Settings的类实例
	//
	//	 Parameters:
	//	 Return Values:
	//	 Author:
	//	      zhengyun@zemo 2005.10.07
	//
	**********************************************************/
	public Settings getRssFeedRecords(){
		return rssRecords;
	}
	
	/**********************************************************
	//	 GUIController::setCurrent()
	//
	//	 Description:
	//	  设置当前显示的界面
	//
	//	 Parameters:
	//	 Return Values:
	//	 Author:
	//	      zhengyun@zemo 2005.10.07
	//
	**********************************************************/
	public void setCurrent(Displayable disp){
		rssMidlet.setCurrent(disp);
    }
	public void setCurrent(Alert alert, Displayable disp){
		rssMidlet.setCurrent(alert, disp);
    }
	
	/**********************************************************
	//	 GUIController::EventID
	//
	//	 Description:
	//	  定义事件ID内部类
	//
	//	 Parameters:
	//	 Return Values:
	//	 Author:
	//	      zhengyun@zemo 2005.10.07
	//
	**********************************************************/
    public static class EventID{
        private EventID(){
        }
        
        public static final byte EVENT_EXIT				= 0;//退出
        public static final byte EVENT_NEW_RECORD 		= 1;//增加
        public static final byte EVENT_NEW_SAVE 			= 2;//保存记录界面的“保存”按钮
        public static final byte EVENT_NEW_BACK 			= 3;//保存记录界面的“返回”按钮
        public static final byte EVENT_DELETE 			= 4;//删除
        public static final byte EVENT_VIEW_DETAIL 		= 5;//察看RSS Feed 的新闻列表
        public static final byte EVENT_VIEW_BACK			= 6;//返回察看
        public static final byte EVENT_EDIT				= 7;//修改
        public static final byte EVENT_EDIT_BACK			= 8;//修改返回
        public static final byte EVENT_EDIT_SAVE			= 9;//保存修改
        public static final byte EVENT_ABOUT				= 10;//保存修改
		public static final byte EVENT_VIEW_RSS_ITEM		= 11;//察看选中的Rss Item的摘要内容
		public static final byte EVENT_VIEW_RSS_ITEM_BACK= 12;//察看选中的Rss Item的摘要内容时的“返回”按钮
		public static final byte EVENT_UPDATE_RSS_ITEMS  = 13;//察看RSS Feed 的新闻列表时的“重新读取新闻”按钮
		public static final byte EVENT_PARSE_RSS_ERROR   = 14;//解析RSS Feed时发生了错误，特此报告
    }
	
	/**********************************************************
	//	 GUIController::deleteAll
	//
	//	 Description:
	//	  将List的所有元素清除
	//
	//	 Parameters:
	//	 Return Values:
	//   Remark:
	 * 由于MIDP 2.0中才定义了List的deleteAll()方法,
	 * 但是MIDP1.0中List支持delete(int itemNum).
	 * 所以在MIDP1.0中,可以使用List的size()得到当前List中的Item的数量,
	 * 然后使用for循环delete(int itemNum),这样在MIDP1.0中实现deleteAll的功能。
	 * 但这么for循环删除有一个非常奇怪的地方,好像是隔一个删一个，导致无法删除干净?!
	 * 所以最后不得不采用while循环删除第一个元素的办法!这也许是一个MIDP1.0的bug。
	 * 
	//	 Author:
	//	      zhengyun@zemo 2005.10.07
	//
	**********************************************************/
	private synchronized void deleteAll()
	{
		System.out.println("!-- GUIController::Enter deleteAll --!");
		
		// 下面的删除代码只能隔一个删一个list的元素，导致无法删除干净
		/*for(int i = 0;i < list();i++){
			
			list.delete(i);
			System.out.println("delete>>" + i);
		}*/
		
		// 这样才能完全删除:
		while(list.size()>0)
			list.delete(0);
	}
	
	/**********************************************************
	//	 GUIController::RefreshList
	//
	//	 Description:
	//	  将List按照新从RMS获取的所有Rss Feed列表进行刷新显示
	//
	//	 Parameters:
	//	 Return Values:
	//   Remark:
	 * 不知道为什么下面这个list.refresh并没有真的把以前的item给删除掉,好像还保留了一半,
	 * 可能还是和for循环删除list元素一样是一个BUG。
	 * 所以我们在采用refresh刷新办法之前,先用我们独特的deleteAll办法自己去删除所有list元素
	 * 以此纠正这个BUG.
	 * 
	//	 Author:
	//	      zhengyun@zemo 2005.10.07
	//
	**********************************************************/
	private synchronized void RefreshList()
	{
		System.out.println("!-- GUIController::Enter RefreshList --!");
				
		deleteAll();
		list.refresh(rssRecords.getRssFeeds());
	}
    
	/**********************************************************
	//	 GUIController::handleEvent
	//
	//	 Description:
	//	  对传入的事件进行处理
	//
	//	 Parameters:
	//	 Return Values:
	//   Remark:
	 * 
	//	 Author:
	**********************************************************/
    public void handleEvent( int eventID,Object[] args){   
    	switch (eventID)
        {   
    	    case EventID.EVENT_EXIT:
    	    {
				System.gc();     // 通知进行垃圾收集
				Thread.yield();  // 本线程暂停一下，使得GC可以马上获得机会运行
				rssMidlet.exit(false);
    	    	break;
    	    }
    	    case EventID.EVENT_VIEW_DETAIL:
    	    {
				setCurrent(openForm);
				openForm.setRss((RssFeed)args[0]);
    	        break;
    	    }
    	    case EventID.EVENT_NEW_RECORD:
    	    {
    	        addForm.clear();
    	    	setCurrent(addForm);
    	    	break;
    	    }
    	    case EventID.EVENT_NEW_BACK:
    	    case EventID.EVENT_VIEW_BACK:    
    	    case EventID.EVENT_EDIT_BACK:
    	    {
    	    	setCurrent(list);
    	    	break;
    	    }
    	    case EventID.EVENT_NEW_SAVE:
    	    {
				RssFeed feed = new RssFeed((String)args[0], (String)args[1]);
				System.out.println("#-- 新建书签的保存:\n名称="
						+ (String)args[0] + "\n链接="
						+ (String)args[1]);
    	        rssRecords.addRssFeed(feed);
				
				// 刷新RssFeed列表
				RefreshList();
    	        setCurrent(list);
    	        break;
    	    }
    	    case EventID.EVENT_EDIT:
    	    {
    	        editForm.setRssFeed((RssFeed)args[0]);
    	        setCurrent(editForm);
    	        break;
    	    }
    	    case EventID.EVENT_EDIT_SAVE:
    	    {
				// 传进去的参数就是feed自身,只不过将用户输入的名称以及链接更新了
				RssFeed feed = (RssFeed)args[0];
				System.out.println("#-- 编辑书签的保存");
				rssRecords.updateRssFeed(feed);
				
				// 刷新RssFeed列表
				RefreshList();
    	        setCurrent(list);
    	        break;
    	    }
    	    case EventID.EVENT_DELETE:
    	    {
				rssRecords.deleteRssFeed(((RssFeed)args[0]).getId());
				
				// 刷新RssFeed列表
				RefreshList();
    	        setCurrent(list);
    	        break;
    	    }
    	    case EventID.EVENT_ABOUT:
    	    {
    	        setCurrent(about);
    	        break;
    	    }
			case EventID.EVENT_VIEW_RSS_ITEM:
    	    {
				viewRssItemForm.setRssItem((RssItem)args[0]);
    	        setCurrent(viewRssItemForm);
    	        break;
    	    }
			case EventID.EVENT_VIEW_RSS_ITEM_BACK:
			{
				setCurrent(openForm);
    	    	openForm.setCurrentDispalyToHeaderList();
    	    	break;
    	    }
			case EventID.EVENT_UPDATE_RSS_ITEMS:
			{
				setCurrent(openForm);
				openForm.updateHeaders();
    	    	break;
    	    }
			case EventID.EVENT_PARSE_RSS_ERROR:
			{
				/*
				 * 发生了某种错误，在获取rss feed资源并且解析XML时
				 */
				String strError = (String)args[0];
				setCurrent(openForm);
				setCurrent(
						new Alert(
								SResources.FORM_TITLE_READRSSFEED, 
								strError, null, AlertType.ERROR),
						(Displayable)openForm);
				break;
			}
         	default:
         	    break;
        }
    }
    
}
